@use 'sass:map';
@use 'config';
@use 'functions';

/* Media Queries */
// TODO: For viewport mixins, future option to not fail if key not found and to ignore instead?
@mixin screen-above($breakpoint) {
    @if not map.has-key($map: config.$breakpoints, $key: $breakpoint) {
        @error 'The given breakpoint #{$breakpoint} for @screen-above does not exist.';
    }

    @media screen and (min-width: map.get(config.$breakpoints, $breakpoint)) {
        @content;
    }
}

@mixin screen-between($lower, $higher) {
    @if not map.has-key($map: config.$breakpoints, $key: $lower) {
        @error 'The given breakpoint #{$lower} ($lower) for @screen-between does not exist.';
    }

    @if not map.has-key($map: config.$breakpoints, $key: $higher) {
        @error 'The given breakpoint #{$higher} ($higher) for @screen-between does not exist.';
    }

    @media screen and (min-width: map.get(config.$breakpoints, $lower)) and (max-width: map.get(config.$breakpoints, $higher) - 1) {
        @content;
    }
}

@mixin screen-below($breakpoint) {
    @if not map.has-key($map: config.$breakpoints, $key: $breakpoint) {
        @error 'The given breakpoint #{$breakpoint} for @screen-below does not exist.';
    }

    @media screen and (max-width: map.get(config.$breakpoints, $breakpoint) - 1) {
        @content;
    }
}

@mixin generate-classes-for-viewport(
    $classes,
    $property,
    $prefix: 'u-',
    $generate-viewports: 'true',
    $include-important: 'true'
) {
    $mapping: functions.to-property-map($classes);

    @include generate-classes-for-viewport-with-map(
        $mapping,
        $property,
        $prefix,
        $generate-viewports,
        $include-important
    );
}

/* Variant of mixin that takes in mapping of class name to value */
@mixin generate-classes-for-viewport-with-map(
    $class-value-pairs,
    $property,
    $prefix: 'u-',
    $generate-viewports: 'true',
    $include-important: 'true'
) {
    $important: if($include-important == 'true', '!important', '');

    @each $class, $value in $class-value-pairs {
        .#{$prefix}#{$class} {
            #{$property}: $value#{$important};
        }
    }

    @if $generate-viewports == 'true' {
        @each $suffix, $limit in config.$breakpoint-pairs {
            @each $class, $value in $class-value-pairs {
                @include screen-above($limit) {
                    .#{$prefix}#{$class}-#{$suffix} {
                        #{$property}: $value#{$important};
                    }
                }
            }
        }
    }
}

/**
 * DART SASS ONLY: Generates viewport classes given styles in a @content mixin
 * 
 * When using this mixin, you must follow specify a mixin that takes in the same number of variables that is being passed into @content below -- in this case, 1.
 * 
 * Example usage (pretend \ is $):
 *      
 *       @include generate-styles-with-viewports('true') using ($viewport) {
 *           $suffix: if($viewport != '', '-#{\viewport}', '');
 *           .outer#{\suffix} {
 *               background: #222;
 *               .inner#{\suffix} {
 *                   color: #fff;
 *               }
 *           }
 *       }
 */
@mixin generate-styles-with-viewports($generate-viewports: 'true') {
    @content ('');

    @if $generate-viewports == 'true' {
        @each $suffix, $limit in config.$breakpoint-pairs {
            @include screen-above($limit) {
                @content ($suffix);
            }
        }
    }
}
